/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mattespill;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import javax.swing.JOptionPane;
/**
 *
 * @author Erik
 */
public class Database implements Serializable {
    private PreparedStatement pstatement = null;
    private Statement statement = null;
    private ResultSet res = null;
    private Connection forbindelse  = null;
    public String feilmelding = "";
    private String dbdriver = "com.mysql.jdbc.Driver";
    private String dbnavn = "nemean5";
    private String dbbrukernavn = "nemean5";
    private String dbpassord = "xxGE8JeF";
    private String dbadresse = "nemean5.mysql.domeneshop.no";
    /**
     * Konstruktør.
     */
    public Database () {
    }
    /**
     * Metode for å koble til databasen.
     */
    public void kobleTil (){    //DriverManager.getConnection("jdbc:mysql://nemean4.mysql.domeneshop.no/nemean4", "nemean4", "Raggy2011")
        try {
            Class.forName(dbdriver);
            String databasenavn = "jdbc:mysql://nemean5.mysql.domeneshop.no/nemean5";
            forbindelse  = DriverManager.getConnection(databasenavn, dbnavn, dbpassord);
        }catch (SQLException e) {
                JOptionPane.showMessageDialog(null,"Feil i kobleTil: "+e+". Avslutter.","Feil",JOptionPane.ERROR_MESSAGE);
        }catch (ClassNotFoundException ex) {
                JOptionPane.showMessageDialog(null,"Feil i kobleTil: "+ex+". Avslutter.","Feil",JOptionPane.ERROR_MESSAGE);
        }
    }
    /**
     * Metode for å koble seg ned fra databasen. Dette brukes for å forhindre at løse ender henger igjen etter endt bruk. Alle metoder
     * som bruker databasen, kobler seg opp og så ned igjen.
     */
    public void kobleFra() {
        try {
            if (res != null) res.close();
        } catch (SQLException e) {
         System.out.println("Feil 3: " + e);
        } finally {
            try {
                if (statement != null) statement.close();
            } catch (SQLException e) {
            System.out.println("Feil 4: " + e);
            } finally {
            try {
                if (forbindelse != null) forbindelse.close();
            } catch (SQLException e) {
            System.out.println("Feil 5:" + e);
            }
         } // finally, lukking av Statement-objekt
       } // finally, lukking av ResultSet-objekt
    }
    /**
     * Metoden legger til en bruker på databasen.
     * @param b Bruker-objektet som skal legges til.
     * @return True/false vellykket lagring eller ikke.
     */
    public boolean leggTilBruker(Bruker b){
        if(b!=null){
            String sql = "insert into bruker (bruker_id, navn, brukernavn,passord, rolle, lagt_til_av) values (DEFAULT,?,?,?,?,?)";
            try {
                pstatement = forbindelse.prepareStatement(sql);
                pstatement.setString(1,b.getNavn());
                pstatement.setString(2,b.getBrukernavn());
                pstatement.setString(3, b.getPassord());
                pstatement.setInt(4, b.getRolle());
                pstatement.setInt(5, b.getLagt_til_av());
                pstatement.executeUpdate();
                statement = forbindelse.createStatement();
                res = statement.executeQuery("select bruker_id from bruker where brukernavn ='"+b.getBrukernavn()+"'");
                int id = 0;
                while(res.next()){
                    id = res.getInt("bruker_id");
                }
                if(lagNyttLagrepunkt(id)){
                    return true;
                }
                return false;
            }catch (SQLException e) {
                feilmelding=""+e;
                return false;
            }
        }
        return false;
    }
    /**
     * Nytt spill?
     * @param id
     * @return
     */
    private boolean lagNyttLagrepunkt(int id){
        try{
            String sql2 = "insert into status (bruker_id,poeng,penger,spill1,spill2,liv) values (?,?,?,?,?,?)";
            pstatement = forbindelse.prepareStatement(sql2);
            pstatement.setInt(1, id);
            pstatement.setInt(2, 0);
            pstatement.setInt(3, 10); //ANTALL STARTKRONER
            pstatement.setInt(4, 0);
            pstatement.setInt(5, 0);
            pstatement.setInt(6, 5); // ANTALL STARTLIV!
            pstatement.executeUpdate();
            return true;
        }catch(SQLException e) {
            feilmelding = ""+e;
            return false;
        }
    }
    public boolean nyttSpill(int id){
        try{
            String sql2 = "update status set poeng=?,penger=?,spill1=?,spill2=?,liv=? where bruker_id = ?";
            pstatement = forbindelse.prepareStatement(sql2);
            pstatement.setInt(1, 0);
            pstatement.setInt(2, 10); //antall spennz
            pstatement.setInt(3, 0);
            pstatement.setInt(4, 0);
            pstatement.setInt(5, 5); //ANtall LIV
            pstatement.setInt(6, id);
            pstatement.executeUpdate();
            return true;
        }catch(SQLException e) {
            feilmelding = ""+e;
            return false;
        }
    }
    /**
     * Metoden sletter en bruker fra databasen.
     * @param b Bruker-objektet som skal slettes.
     * @return True/false om det gikk eller ikke.
     */
    public boolean slettBruker(Bruker b){
        if(b!=null){
            slettInformasjonOmBruker(b);
            String sql = "delete from bruker where bruker_id = ?";
            try {
                pstatement = forbindelse.prepareStatement(sql);
                pstatement.setInt(1,b.getBruker_id());
                pstatement.executeUpdate();
                return true;
            }catch (SQLException e) {
                feilmelding=""+e;
                return false;
            }
        }
        return false;
    }
    private boolean slettInformasjonOmBruker(Bruker b){
        String sql = "delete from status where bruker_id = ?";
        try {
            pstatement = forbindelse.prepareStatement(sql);
            pstatement.setInt(1,b.getBruker_id());
            pstatement.executeUpdate();
            String sql2 = "delete from statushistorikk where bruker_id = ?";
            pstatement = forbindelse.prepareStatement(sql2);
            pstatement.setInt(1,b.getBruker_id());
            pstatement.executeUpdate();
            return true;
        }catch (SQLException e) {
            feilmelding=""+e;
            return false;
        }
    }
    /**
     * Metoden endrer en allerede registrert bruker
     * @param b Brukeren som skal endres med de nye variablene.
     * @return True/false om det gikk eller ikke.
     */
    public boolean endreBruker(Bruker b){
        if(b!=null){
            String sql = "update bruker set navn = ?, brukernavn = ?, passord = ?, rolle = ?, lagt_til_av = ? where bruker_id = ?";
            try {
                pstatement = forbindelse.prepareStatement(sql);
                pstatement.setInt(6,b.getBruker_id());
                pstatement.setString(1,b.getNavn());
                pstatement.setString(2,b.getBrukernavn());
                pstatement.setString(3, b.getPassord());
                pstatement.setInt(4, b.getRolle());
                pstatement.setInt(5,b.getLagt_til_av());
                pstatement.executeUpdate();
                return true;
            }catch (SQLException e) {
                feilmelding=""+e;
                return false;
            }
        }
        return false;
    }
    /**
     * Metoden henter brukere med en spesiell rolle fra databasen
     * @param rolle Rolletypen som ønskes (0 for elev, 1 for faglærer)
     * @return En arraylist av brukere.
     */
    public ArrayList<Bruker> getAlleBrukere(int rolle){
        ArrayList<Bruker> temp = new ArrayList<Bruker>();
        try {
            statement = forbindelse.createStatement();
            res = statement.executeQuery("select * from bruker where rolle = "+rolle+" ");
            while(res.next()){
                temp.add(new Bruker(res.getInt("bruker_id"),res.getString("navn"),res.getString("brukernavn"),res.getString("passord"),res.getInt("rolle"),res.getInt("lagt_til_av")));
            }
            return temp;
        }catch (SQLException e){
            feilmelding = ""+e;
            return null;
        }
    }
    /**
     * Lagringsfunksjonen. Denne øker tabellen til spill X med et gitt antall poeng basert på nivå, samt øker poengsummen med samme poengsum.
     * @param bruker_id Id'en til brukeren som skal økes.
     * @param spill SpillID'en.
     * @param nivaa Poengsummen baseres på hvilket nivå brukeren er på.
     * @return
     */
    public boolean leggTilFullfortOppgave(int bruker_id, int spill, int nivaa){
        if(bruker_id != 0 && spill >= 1 && spill <= 6){
            String spillet = "spill"+spill;
            String sql = "update status set "+spillet+" = ?, poeng = ? , sistespill= "+spill+" where bruker_id ="+bruker_id+"";
            try {
                statement = forbindelse.createStatement();
                res = statement.executeQuery("select * from status where bruker_id = "+bruker_id+" ");
                int tidligereSpill = 0;
                int tidligerePoeng = 0;
                while(res.next()){
                    tidligereSpill = res.getInt(spillet);
                    tidligerePoeng = res.getInt("poeng");
                }

                pstatement = forbindelse.prepareStatement(sql);
                pstatement.setInt(1, tidligereSpill+1); // ØKER SPILLKOLONNEN MED 1,
                pstatement.setInt(2, tidligerePoeng+nivaa); // ØKER POENGSUM MED POENG
                pstatement.executeUpdate();
                return true;
            }catch (SQLException e) {
                feilmelding=""+e;
                return false;
            }
        }
        return false;
    }
    public boolean mistLiv(int bruker_id){
        try{
            statement = forbindelse.createStatement();
            res = statement.executeQuery("select * from status where bruker_id = "+bruker_id+" ");
            int tidligereLiv = 0;
            while(res.next()){
                tidligereLiv = res.getInt("liv");
            }
            if(tidligereLiv-1==0){
                //GAME OVER!!
                lagreStatus(bruker_id,getStatus(bruker_id));
                return false;
            }
            String sql2 = "update status set liv = ? where bruker_id = ?";
            pstatement = forbindelse.prepareStatement(sql2);
            pstatement.setInt(1,tidligereLiv-1);
            pstatement.setInt(2, bruker_id);
            pstatement.executeUpdate();
            return true;
        }catch(SQLException e) {
            feilmelding = ""+e;
            return false;
        }
    }
    private boolean lagreStatus(int bruker_id, Status s){
        try{
            String sql2 = "insert into statushistorikk (bruker_id,poeng,spill1,spill2) values (?,?,?,?)"; //spill1,spill2 finnes også
            pstatement = forbindelse.prepareStatement(sql2);
            pstatement.setInt(1, bruker_id);
            pstatement.setInt(2, s.getPoeng());
            pstatement.setInt(3,s.getSpill1());
            pstatement.setInt(4,s.getSpill2());
            pstatement.executeUpdate();
            return true;
        }catch(SQLException e) {
            feilmelding = ""+e;
            return false;
        }
    }
    /**
     * Metoden finner elevene til faglærer.
     * @param faglaerer_id Id'en til læreren.
     * @return En ArrayList over elevene.
     */
    public ArrayList<Bruker> getElever(int faglaerer_id){
        ArrayList<Bruker> temp = new ArrayList<Bruker>();
        try {
            statement = forbindelse.createStatement();
            res = statement.executeQuery("select * from bruker where lagt_til_av = "+faglaerer_id+" ");
            while(res.next()){
                temp.add(new Bruker(res.getInt("bruker_id"),res.getString("navn"),res.getString("brukernavn"),res.getString("passord"),res.getInt("rolle"),res.getInt("lagt_til_av")));
            }
            return temp;
        }catch (SQLException e){
            feilmelding = ""+e;
            return null;
        }
    }
    public ArrayList<BrukerStatus> getBrukerStatus(int faglaerer_id){
        ArrayList<BrukerStatus> temp = new ArrayList<BrukerStatus>();
        ArrayList bruker_id = new ArrayList();
        ArrayList poeng = new ArrayList();
        try {
            statement = forbindelse.createStatement();
            res = statement.executeQuery("select max(poeng) as \"poeng\",bruker_id from statushistorikk group by bruker_id");
            while(res.next()){
                bruker_id.add(res.getInt("bruker_id"));
                poeng.add(res.getInt("poeng"));
            }
            for(int i=0;i<bruker_id.size();i++){
              statement = forbindelse.createStatement();
                res = statement.executeQuery("select * from statushistorikk join bruker on bruker.bruker_id = statushistorikk.bruker_id where bruker.lagt_til_av = "+faglaerer_id+" and statushistorikk.poeng="+poeng.get(i)+" and bruker.bruker_id="+bruker_id.get(i)+" order by poeng desc");
                while(res.next()){
                    temp.add(new BrukerStatus(new Bruker(res.getInt("bruker_id"),res.getString("navn"),res.getString("brukernavn"),res.getString("passord"),res.getInt("rolle"),res.getInt("lagt_til_av"))
                            ,new Status(res.getInt("spill1"),res.getInt("spill2"),res.getInt("poeng"))));
                }
            }
            
            return temp;
        }catch (SQLException e){
            System.out.println(e);
            return null;
        }
    }
    public ArrayList<BrukerStatus> getHighscore(){
        ArrayList<BrukerStatus> temp = new ArrayList<BrukerStatus>();
        try {
            statement = forbindelse.createStatement();
            res = statement.executeQuery("select * from statushistorikk join bruker on bruker.bruker_id = statushistorikk.bruker_id where poeng != 0 order by poeng desc");
            while(res.next()){
                temp.add(new BrukerStatus(new Bruker(res.getInt("bruker_id"),res.getString("navn"),res.getString("brukernavn"),res.getString("passord"),res.getInt("rolle"),res.getInt("lagt_til_av"))
                        ,new Status(res.getInt("spill1"),res.getInt("spill2"),res.getInt("poeng"))));
            }
            return temp;
        }catch (SQLException e){
            feilmelding = ""+e;
            return null;
        }
    }
    public boolean finnesStatus(int bruker_id){
        boolean sta = false;
        try{
            statement = forbindelse.createStatement();
            res = statement.executeQuery("select * from status join bruker on bruker.bruker_id = status.bruker_id where status.bruker_id = "+bruker_id+" and poeng > 0");
            while(res.next()){
                sta =  true;
            }
            return sta;
        }catch (SQLException e){
            feilmelding = ""+e;
            return sta;
        }
    }
    public Status getStatus(int bruker_id){
        Status sta = null;
        try{
            statement = forbindelse.createStatement();
            res = statement.executeQuery("select * from status join bruker on bruker.bruker_id = status.bruker_id where status.bruker_id = "+bruker_id+" ");
            while(res.next()){
                sta =  new Status(res.getInt("spill1"),res.getInt("spill2"),res.getInt("poeng"),res.getInt("penger"),res.getInt("liv"),res.getInt("sistespill"));
            }
            return sta;
        }catch (SQLException e){
            feilmelding = ""+e;
            return null;
        }
    }
    public int getPoeng(int bruker_id){
        Status sta = null;
        int poeng = 0;
        try{
            statement = forbindelse.createStatement();
            res = statement.executeQuery("select * from status where bruker_id = "+bruker_id+" ");
            while(res.next()){
                poeng =  res.getInt("poeng");
            }
            return poeng;
        }catch (SQLException e){
            feilmelding = ""+e;
            return -1;
        }
    }
    /**
     * Metoden legger til en poengsum til tabellen poeng i databasen.
     * @param bruker_id
     * @param poengsum
     * @param spill
     * @return
     */
   /* public boolean leggTilPoeng(int bruker_id, int poengsum, int spill){
        if(bruker_id != 0 && poengsum != 0 && spill != 0){
            String sql = "insert into poeng (bruker_id,poeng,spill) values (?,?,?)";
            try {
                pstatement = forbindelse.prepareStatement(sql);
                pstatement.setInt(1, bruker_id);
                pstatement.setInt(2, poengsum);
                pstatement.setInt(3, spill);
                pstatement.executeUpdate();
                return true;
            }catch (SQLException e) {
                feilmelding=""+e;
                return false;
            }
        }
        return false;
    }
    *
    */
    //public Poeng getPoengSpill(int spill)
    public boolean loggInn(String brukernavn, String passord){
        boolean finnes = false;
        if(brukernavn != null && passord != null){
            try {
                statement = forbindelse.createStatement();
                res = statement.executeQuery("select * from bruker where brukernavn = '"+brukernavn+"' and passord ='"+passord+"' ");
                while(res.next()){
                    finnes = true;
                }
            }catch (SQLException e) {
                feilmelding=""+e;
                finnes = false;
            }
        }
        return finnes;
    }
    /**
     * Trekker 1 mynt fra brukeren.
     * @param bruker_id
     * @return
     */
    public boolean trekkPenger(int bruker_id){
        if(bruker_id != 0){
            try{
                statement = forbindelse.createStatement();
                res = statement.executeQuery("select * from status where bruker_id = "+bruker_id+" ");
                int tidligerePenger = 0;
                while(res.next()){
                    tidligerePenger = res.getInt("penger");
                }
                if(tidligerePenger==0){
                    //Ikke mer penger igjen.
                    return false;
                }
                String sql2 = "update status set penger = ? where bruker_id = ?";
                pstatement = forbindelse.prepareStatement(sql2);
                pstatement.setInt(1,tidligerePenger-5);
                pstatement.setInt(2, bruker_id);
                pstatement.executeUpdate();
                return true;
            }catch(SQLException e){
                feilmelding = ""+e;
                return false;
            }
        }
        return false;
    }
    public boolean giPenger(int bruker_id){
        if(bruker_id != 0){
            try{
                statement = forbindelse.createStatement();
                res = statement.executeQuery("select * from status where bruker_id = "+bruker_id+" ");

                int tidligerePenger = 0;
                while(res.next()){
                    tidligerePenger = res.getInt("penger");
                }
                String sql2 = "update status set penger = ? where bruker_id = ?";
                pstatement = forbindelse.prepareStatement(sql2);

                pstatement.setInt(1,tidligerePenger+10);
                pstatement.setInt(2, bruker_id);
                pstatement.executeUpdate();
                return true;
            }catch(SQLException e){
                feilmelding = ""+e;
                return false;
            }
        }
        return false;
    }
    public boolean finnesPenger(int bruker_id){
        if(bruker_id!=0){
            try{
                statement = forbindelse.createStatement();
                res = statement.executeQuery("select * from status where bruker_id = "+bruker_id+" ");
                int penger = 0;
                while(res.next()){
                    penger = res.getInt("penger");
                }
                if(penger == 0){
                    return false;
                }else{
                    return true;
                }
            }catch(SQLException e){
                feilmelding = ""+e;
                return false;
            }
        }
        return false;
    }
    public Bruker getBruker(String brukernavn){
        Bruker b = null;
        if(brukernavn != null){
            try {
                statement = forbindelse.createStatement();
                res = statement.executeQuery("select * from bruker where brukernavn = '"+brukernavn+"' ");
                while(res.next()){
                    b = new Bruker(res.getInt("bruker_id"),res.getString("navn"),res.getString("brukernavn"),res.getString("passord"),res.getInt("rolle"),res.getInt("lagt_til_av"));
                }
            }catch(SQLException e){
            }
        }
        return b;
    }
    public Bruker getBruker(int bruker_id){
        Bruker b = null;
        if(bruker_id != 0){
            try {
                statement = forbindelse.createStatement();
                res = statement.executeQuery("select * from bruker where bruker_id = "+bruker_id+" ");
                while(res.next()){
                    b = new Bruker(res.getInt("bruker_id"),res.getString("navn"),res.getString("brukernavn"),res.getString("passord"),res.getInt("rolle"),res.getInt("lagt_til_av"));
                }
            }catch(SQLException e){
            }
        }
        return b;
    }
    public boolean nullstillHighscore(){
        try {
                pstatement = forbindelse.prepareStatement("delete from statushistorikk");
                pstatement.executeUpdate();
                return true;
            }catch(SQLException e){
                System.out.println("Feil i nullstillhighscore " + e);
                return false;
            }
    }
}
